跳到主要内容

Go 1.18 特性学习

注意下载对应自己系统,以及架构的 SDK

配置 VSCode

注意安装 1.18 版本的 Go SDK 需要先删掉 go 目录下的文件,否则会报错

go install golang.org/dl/go1.18@latest
go1.18 download

ctrl + shift + p

Go: Install/Update Tools

泛型学习

快速使用

官方给了个泛型的例子

如下,在以前版本每个类型都需要添加一个不同类型的方法

// SumInts adds together the values of m.
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}

// SumFloats adds together the values of m.
func SumFloats(m map[string]float64) float64 {
var s float64
for _, v := range m {
s += v
}
return s
}

使用泛型后:

// SumIntsOrFloats sums the values of map m. It supports both int64 and float64
// as types for map values.
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}

测试:

func main() {
ints := map[string]int64{
"first": 34,
"second": 12,
}

// Initialize a map for the float values
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
}

fmt.Println(SumIntsOrFloats(ints))
fmt.Println(SumIntsOrFloats(floats))
}
$ go run .
46
62.97

max 和 min

package main

import (
"fmt"
)

func main() {
fmt.Println(Max(1, 2))
}

// Int 所有底层类型为为int/int8...等,均符合Int泛型定义
type Int interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Uint interface {
uint | uint8 | uint16 | uint32 | uint64
}

type Float interface {
float32 | float64
}

// Number 包含了所有数字的定义
type Number interface {
Int | Uint | Float
}
type ordered interface {
Int | Uint | uintptr | Float | string
}

func Max[T ordered](a, b T) T {
if a < b {
return b
}
return a
}

func Min[T ordered](a, b T) T {
if a > b {
return b
}
return a
}

any 类型

自动把项目下的全部 interface{} 转成 any 类型

gofmt -w -r 'interface{} -> any' src

如果要兼容 Go 1.17 或之前的版本吗,则需要在每个包下面都加一个 any.go 文件

// +build !go1.18
//go:build !go1.18

package main

type any = interface{}

使用条件编译

声明类型限制

type Number interface {
int64 | float64
}

在这段代码里,声明了一个名为 Number 的接口类型用于类型限制,在接口定义里,声明了 int64 和 float64 的并集

把原本来函数声明里的 int64 和 float64 的并集改造成了一个新的类型限制接口 Number,当需要限制类型参数为 int64 或 float64 时,就可以使用 Number 这个类型限制来代替 int64 | float64 的写法。

// SumNumbers sums the values of map m. Its supports both integers
// and floats as map values.
func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}

~ 表示底层类型

~T: ~ 是 Go 1.18 新增的符号,~T 表示底层类型是 T 的所有类型。例如 ~int 表示底层类型为 int 的类型,type MyInt int,则 MyInt 符合 ~int 的定义

comparable 可比较类型

comparable 是新增的可比较类型

常用的泛型

这里对常用的泛型进行了一个归纳,在后续的泛型编程中,可以直接使用

// Signed 有符号整数
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}

// Unsigned 无符号整数
type Unsigned interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}

// Integer 所有整数
type Integer interface {
Signed | Unsigned
}

// Float 浮点数
type Float interface {
~float32 | ~float64
}

// Complex 复数
type Complex interface {
~complex64 | ~complex128
}

// Ordered 支持比较的类型
type Ordered interface {
Integer | Float | ~string
}

// Slice 任意类型的 slice
type Slice[Elem any] interface {
~[]Elem
}

// Map 任意类型的 map
type Map[Key comparable, Val any] interface {
~map[Key]Val
}

// Chan 任意类型的 channel
type Chan[Elem any] interface {
~chan Elem
}

References